package com.central.gateway.config;

import com.central.common.constant.SecurityConstants;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import reactor.core.publisher.Mono;

/**
 * 定义spring cloud gateway中的 key-resolver: "#{@ipAddressKeyResolver}"
 * #SPEL表达式去的对应的bean ipAddressKeyResolver 要取bean的名字
 *
 */
@Configuration
public class RateLimiterConfiguration {

    /**
     * 接口限流：根据请求路径限流
     * @return
     */
    /*
         如果不使用@Primary注解，会报如下错误，需要注意
    Description:
    Parameter 1 of method requestRateLimiterGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a single bean, but 3 were found:
            - pathKeyResolver: defined by method 'pathKeyResolver' in class path resource [com/mkevin/gateway/config/RateLimiteConfig.class]
            - ipKeyResolver: defined by method 'ipKeyResolver' in class path resource [com/mkevin/gateway/config/RateLimiteConfig.class]
            - userKeyResolver: defined by method 'userKeyResolver' in class path resource [com/mkevin/gateway/config/RateLimiteConfig.class]
    Action:
    Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier
    to identify the bean that should be consumed
    */
    @Bean
    @Primary
    public KeyResolver pathKeyResolver() {
        //写法1
        return exchange -> Mono.just(
                exchange.getRequest()
                        .getPath()
                        .toString()
        );
    }

    /**
     * 根据请求IP限流
     * @return
     */
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest()
                        .getRemoteAddress()
                        .getHostName()
        );
    }

    /**
     * 根据请求参数中的userId进行限流
     */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest().getHeaders().getFirst(SecurityConstants.USER_ID_HEADER)
        );
    }



    /**
     * 根据租户ID进行限流
     */
    @Bean
    public KeyResolver tenantKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest().getHeaders().getFirst(SecurityConstants.TENANT_HEADER)
        );
    }


}
